package com.jft.spread.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jft.spread.cache.CachePrefix;
import com.jft.spread.context.UserContext;
import com.jft.spread.mapper.UserMapper;
import com.jft.spread.pojo.dos.UserDO;
import com.jft.spread.pojo.enums.UserEnums;
import com.jft.spread.pojo.req.UserLoginReqVO;
import com.jft.spread.pojo.req.UserPasswordReqVO;
import com.jft.spread.pojo.req.UserReqVO;
import com.jft.spread.pojo.vo.AuthUser;
import com.jft.spread.service.UserLoginService;
import com.jft.spread.token.Token;
import com.jft.spread.token.TokenUtil;
import com.jft.spread.utils.RedisUtil;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;

@Service
public class UserLoginServiceImpl implements UserLoginService {

    @Resource
    private TokenUtil tokenUtil;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisUtil redisUtil;

    @Override
    public Token passwordLogin(UserLoginReqVO reqVO) {
        if (reqVO.getPhone().length() != 11) {
            throw new IllegalArgumentException("手机号格式错误！");
        }
        UserDO companyEmployeesDO = userMapper.selectOne(new LambdaQueryWrapper<UserDO>()
                .eq(UserDO::getPhone, reqVO.getPhone())
                .eq(UserDO::getDel, 0)
                .last("LIMIT 1"));
        if (Objects.isNull(companyEmployeesDO)) {
            throw new IllegalArgumentException("员工不存在！");
        }
        // 校验密码
        if (!new BCryptPasswordEncoder().matches(reqVO.getPassword(), companyEmployeesDO.getPassword())) {
            throw new IllegalArgumentException("密码不正确！");
        }
        userMapper.update(new UserDO(), new LambdaUpdateWrapper<UserDO>()
                .set(UserDO::getLoginTime, new Date())
                .eq(UserDO::getId, companyEmployeesDO.getId()));
        // 生成token
        AuthUser authUser = AuthUser.builder()
                .id(companyEmployeesDO.getId())
                .phone(companyEmployeesDO.getPhone())
                .name(companyEmployeesDO.getName())
                .invitationCode(companyEmployeesDO.getInvitationCode())
                .role(UserEnums.STAFF)
                .longTerm(true)
                .build();
        return tokenUtil.createToken(authUser);
    }

    @Override
    public Token updatePassword(UserPasswordReqVO reqVO) {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (Objects.isNull(currentUser)) {
            throw new IllegalArgumentException("用户信息异常，请重新登录！");
        }
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(reqVO.getPassword());
        userMapper.update(new UserDO(), new LambdaUpdateWrapper<UserDO>()
                .set(UserDO::getLoginTime, new Date())
                .set(UserDO::getPassword, encode)
                .eq(UserDO::getId, currentUser.getId()));
        // 生成token
        AuthUser authUser = AuthUser.builder()
                .id(currentUser.getId())
                .phone(currentUser.getPhone())
                .name(currentUser.getName())
                .invitationCode(currentUser.getInvitationCode())
                .role(UserEnums.STAFF)
                .longTerm(true)
                .build();
        return tokenUtil.createToken(authUser);
    }

    @Override
    public Token refreshToken(String accessToken) {
        return tokenUtil.refreshToken(accessToken);
    }

    @Override
    public void outLogin(String accessToken) {
        AuthUser authUser = UserContext.getCurrentUser();
        String access = CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.STAFF, authUser.getId()) + accessToken;
        String refresh = CachePrefix.REFRESH_TOKEN.getPrefix(UserEnums.STAFF, authUser.getId()) + accessToken;
        redisUtil.del(access, refresh);
    }


    @Override
    public List<UserDO> selectUser(UserLoginReqVO userLoginReqVO) {
        System.out.println("-----------" + userLoginReqVO);
//        return userMapper.selectUser(userLoginReqVO);

        return userMapper.selectList(new LambdaQueryWrapper<UserDO>()
                .eq(UserDO::getPhone, userLoginReqVO.getPhone()));
    }

    @Override
    public List<UserDO> selectUserOne(UserLoginReqVO userDO) {
        return userMapper.selectList(new LambdaQueryWrapper<UserDO>()
                .eq(UserDO::getPhone, userDO.getPhone())
                .last("LIMIT 1"));
    }

    @Override
    public void insertUserOne(UserReqVO userReqVO) {
        UserDO userDO = new UserDO();
        BeanUtil.copyProperties(userReqVO, userDO);
        userDO.setCreateTime(new Date());
        userDO.setLoginTime(new Date());
        String PassWord = userReqVO.getPassword();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(PassWord);
        userDO.setPassword(encode);
        UserDO userDO2 = userMapper.selectOne(new LambdaQueryWrapper<UserDO>()
                .eq(UserDO::getPhone, userDO.getPhone())
                .last("LIMIT 1"));
        if (Objects.nonNull(userDO2)) {
            throw new IllegalArgumentException("手机号已存在！");
        }
        while (true) {
            //生成邀请码
            String invitation = invitation();
            UserDO userDO1 = userMapper.selectOne(new LambdaQueryWrapper<UserDO>()
                    .eq(UserDO::getInvitationCode, invitation)
                    .last("LIMIT 1"));
            if (Objects.isNull(userDO1)) {
                userDO.setInvitationCode(invitation);
                break;
            }
        }


        userMapper.insert(userDO);
    }

    public String invitation() {
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        int codeLength = 8;
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < codeLength; i++) {
            int randomIndex = random.nextInt(characters.length());
            char randomChar = characters.charAt(randomIndex);
            code.append(randomChar);
        }
        return code.toString();
    }

    @Override
    public Token updateUserOne(UserReqVO userDO) {
        AuthUser currentUser = UserContext.getCurrentUser();
        if (Objects.isNull(currentUser)) {
            throw new IllegalArgumentException("用户信息异常，请重新登录！");
        }
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(userDO.getPassword());
        userMapper.update(new UserDO(), new LambdaUpdateWrapper<UserDO>()
                .set(UserDO::getLoginTime, new Date())
                .set(UserDO::getPassword, encode)
                .eq(UserDO::getId, currentUser.getId()));
        // 生成token
        AuthUser authUser = AuthUser.builder()
                .id(currentUser.getId())
                .phone(currentUser.getPhone())
                .name(currentUser.getName())
                .invitationCode(currentUser.getInvitationCode())
                .role(UserEnums.STAFF)
                .longTerm(true)
                .build();
        return tokenUtil.createToken(authUser);

    }
}
